commonlibsse_ng\re\h/
hkRefPtr.rs1use std::marker::PhantomData;
8use std::ops::{Deref, DerefMut};
9use std::ptr;
10
11use crate::re::hkaMirroredSkeleton;
12
13#[repr(C)]
15pub struct hkRefPtr<T>
16where
17 T: hkRefPtrCounted,
18{
19 _ptr: *mut T,
22 _marker: PhantomData<T>,
24}
25
26const _: () = {
28 assert!(core::mem::size_of::<hkRefPtr<hkaMirroredSkeleton>>() == 0x8);
29};
30
31pub trait hkRefPtrCounted {
32 fn AddReference(&self) {}
33 fn RemoveReference(&self) {}
34}
35
36impl<T> hkRefPtr<T>
37where
38 T: hkRefPtrCounted,
39{
40 #[inline]
42 pub const fn new() -> Self {
43 Self { _ptr: ptr::null_mut(), _marker: PhantomData }
44 }
45
46 #[inline]
48 pub fn from_raw(ptr: *mut T) -> Self {
49 let mut ref_ptr = Self { _ptr: ptr, _marker: PhantomData };
50 ref_ptr.try_attach();
51 ref_ptr
52 }
53
54 #[inline]
56 pub fn reset(&mut self) {
57 self.try_detach();
58 }
59
60 #[inline]
62 pub fn reset_with(&mut self, ptr: *mut T) {
63 if self._ptr != ptr {
64 self.try_detach();
65 self._ptr = ptr;
66 self.try_attach();
67 }
68 }
69
70 #[inline]
72 pub const fn get(&self) -> *mut T {
73 self._ptr
74 }
75
76 #[inline]
78 pub const fn is_some(&self) -> bool {
79 !self._ptr.is_null()
80 }
81
82 #[inline]
84 fn try_attach(&mut self) {
85 if !self._ptr.is_null() {
86 unsafe {
87 (*self._ptr).AddReference();
88 }
89 }
90 }
91
92 #[inline]
94 fn try_detach(&mut self) {
95 if !self._ptr.is_null() {
96 unsafe {
97 (*self._ptr).RemoveReference();
98 }
99 self._ptr = ptr::null_mut();
100 }
101 }
102}
103
104impl<T> Default for hkRefPtr<T>
105where
106 T: hkRefPtrCounted,
107{
108 #[inline]
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl<T> Clone for hkRefPtr<T>
115where
116 T: hkRefPtrCounted,
117{
118 #[inline]
119 fn clone(&self) -> Self {
120 let mut ref_ptr = Self { _ptr: self._ptr, _marker: PhantomData };
121 ref_ptr.try_attach();
122 ref_ptr
123 }
124}
125
126impl<T> Drop for hkRefPtr<T>
127where
128 T: hkRefPtrCounted,
129{
130 #[inline]
131 fn drop(&mut self) {
132 self.try_detach();
133 }
134}
135
136impl<T> Deref for hkRefPtr<T>
137where
138 T: hkRefPtrCounted,
139{
140 type Target = T;
141
142 #[inline]
143 fn deref(&self) -> &Self::Target {
144 assert!(!self._ptr.is_null(), "Dereferencing a nullptr");
145 unsafe { &*self._ptr }
146 }
147}
148
149impl<T> DerefMut for hkRefPtr<T>
150where
151 T: hkRefPtrCounted,
152{
153 #[inline]
154 fn deref_mut(&mut self) -> &mut Self::Target {
155 assert!(!self._ptr.is_null(), "Dereferencing a nullptr");
156 unsafe { &mut *self._ptr }
157 }
158}
159
160impl<T> PartialEq for hkRefPtr<T>
161where
162 T: hkRefPtrCounted,
163{
164 #[inline]
165 fn eq(&self, other: &Self) -> bool {
166 self.get() == other.get()
167 }
168}
169
170impl<T> Eq for hkRefPtr<T> where T: hkRefPtrCounted {}
171
172impl<T> std::fmt::Debug for hkRefPtr<T>
173where
174 T: hkRefPtrCounted,
175{
176 #[inline]
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 f.debug_struct("hkRefPtr").field("ptr", &self._ptr).finish()
179 }
180}
181
182#[inline]
184pub fn make_hkref<T>(value: T) -> hkRefPtr<T>
185where
186 T: hkRefPtrCounted,
187{
188 let boxed = Box::new(value);
189 hkRefPtr::from_raw(Box::into_raw(boxed))
190}
191
192impl<T> PartialEq<std::ptr::NonNull<T>> for hkRefPtr<T>
194where
195 T: hkRefPtrCounted,
196{
197 #[inline]
198 fn eq(&self, other: &std::ptr::NonNull<T>) -> bool {
199 self.get() == other.as_ptr()
200 }
201}
202
203impl<T> PartialEq<*mut T> for hkRefPtr<T>
204where
205 T: hkRefPtrCounted,
206{
207 #[inline]
208 fn eq(&self, other: &*mut T) -> bool {
209 self.get() == *other
210 }
211}